﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.AutomaticPathPlanner.Planner.CApAPPSegmentPlanCommand
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using System.Diagnostics;


namespace DnProcessSimulateCommands.AutomaticPathPlanner.Planner;

public class CApAPPSegmentPlanCommand
{
  private CApAPPSubTask m_subtaskToPlan;
  private KiAppPathPlanningParamsEx m_pathPlanningParams;
  private bool m_wasPlanningCancelled;
  private bool m_isPlanned;
  private bool m_shouldSkip;
  private bool m_isFinished;
  private bool m_isStarted;
  private bool m_wasPlanningSuccessful;
  private bool m_wasPlanningTimeOut;
  private Stopwatch m_elapsedTimer;
  private Stopwatch m_elapsedTimerForTimeOut;
  private double m_progress;
  private readonly bool m_optimize;
  private readonly CApAPPSegmentPlanOption m_planOption;

  public CApAPPSegmentPlanCommand(
    CApAPPSubTask i_subtask,
    KiAppPathPlanningParamsEx i_pathPlanningParams,
    bool i_optimize)
    : this(i_subtask, i_pathPlanningParams, i_optimize, CApAPPSegmentPlanOption.AppPath)
  {
  }

  public CApAPPSegmentPlanCommand(
    CApAPPSubTask i_subtask,
    KiAppPathPlanningParamsEx i_pathPlanningParams,
    bool i_optimize,
    CApAPPSegmentPlanOption planOption)
  {
    this.m_subtaskToPlan = i_subtask;
    this.m_pathPlanningParams = i_pathPlanningParams;
    this.m_wasPlanningCancelled = false;
    this.m_wasPlanningTimeOut = false;
    this.m_wasPlanningSuccessful = false;
    this.m_optimize = i_optimize;
    this.m_planOption = planOption;
    this.m_isPlanned = true;
    this.m_shouldSkip = false;
  }

  public CApAPPSubTask SubtaskToPlan => this.m_subtaskToPlan;

  public KiAppPathPlanningParamsEx PathPlanningParams => this.m_pathPlanningParams;

  public void OnStartThread()
  {
    this.m_isStarted = true;
    this.m_isFinished = false;
    this.m_elapsedTimer = new Stopwatch();
    this.m_elapsedTimerForTimeOut = new Stopwatch();
    this.m_elapsedTimer.Start();
    this.m_elapsedTimerForTimeOut.Start();
    this.m_progress = 0.0;
    while (!this.m_isFinished)
    {
      this.onIdle();
      if (this.m_elapsedTimer.ElapsedMilliseconds > 1000L)
      {
        this.m_progress = KiAppSegmentPlanCommandEx.GetPlanProgress(this.SubtaskToPlan.KiSubTask);
        this.m_elapsedTimer.Restart();
      }
    }
  }

  public bool IsFinished() => this.m_isFinished;

  public bool WasPlanningSuccessful()
  {
    int o_firstIndex = 0;
    int o_secondIndex = 0;
    this.m_subtaskToPlan.WaypointIndexes(ref o_firstIndex, ref o_secondIndex);
    if (o_secondIndex == o_firstIndex + 1 && this.m_subtaskToPlan.Task is CApAPPRoboticTask task)
    {
      int num = task.RetrieveWaypointIndexFromSubTask(this.m_subtaskToPlan);
      if ((task.KiTask as KiAppRoboticTaskEx).IsDepartOrApproachWaypoint(num - 1, num) || (task.KiTask as KiAppRoboticTaskEx).IsDepartOrApproachWaypoint(num, num - 1))
        this.m_wasPlanningSuccessful = true;
    }
    return this.m_wasPlanningSuccessful;
  }

  public bool WasPlanningTimeOut() => this.m_wasPlanningTimeOut;

  public void IsPlanned(bool i_isPlanned) => this.m_isPlanned = i_isPlanned;

  public bool IsPlanned() => this.m_isPlanned;

  public double GetProgress() => this.m_isFinished ? 1.0 : this.m_progress;

  public void Cancel() => this.m_wasPlanningCancelled = true;

  public bool WasPlanningCancelled() => this.m_wasPlanningCancelled;

  public CApAPPPlanSuccess PlanSuccess()
  {
    CApAPPPlanSuccess capAppPlanSuccess = CApAPPPlanSuccess.SUCCESS_PREPROCESSING;
    if (this.IsPlanned())
    {
      if (this.WasPlanningSuccessful())
        capAppPlanSuccess = CApAPPPlanSuccess.SUCCESS;
      if (this.WasPlanningTimeOut())
        capAppPlanSuccess = CApAPPPlanSuccess.TIMEOUT_ERROR;
      else if (this.WasPlanningCancelled())
        capAppPlanSuccess = CApAPPPlanSuccess.SKIP;
      else if (!this.m_isFinished)
        capAppPlanSuccess = this.m_isStarted ? CApAPPPlanSuccess.WAIT : CApAPPPlanSuccess.WAIT_BEFORE_START;
      else if (!this.WasPlanningSuccessful())
        capAppPlanSuccess = CApAPPPlanSuccess.CLASH_ERROR;
    }
    return capAppPlanSuccess;
  }

  public void onIdle()
  {
    if (this.m_wasPlanningCancelled)
      this.EndPlanning(false);
    else if (this.m_shouldSkip)
      this.SkipPlanning();
    else
      this.ContinuePlanning();
  }

  protected virtual bool DoStartPlanning(ref bool o_shouldContinue)
  {
    return KiAppSegmentPlanCommandEx.StartPlanning(this.m_subtaskToPlan.KiSubTask, this.m_pathPlanningParams, this.m_optimize, (KiAppSegmentPlanCommandEx.KiAppSegmentPlanAlgorithmType) this.m_planOption, ref o_shouldContinue);
  }

  public bool StartPlanning()
  {
    this.m_isStarted = true;
    bool o_shouldContinue = true;
    bool flag = this.DoStartPlanning(ref o_shouldContinue);
    this.m_shouldSkip = !o_shouldContinue;
    if (!flag)
    {
      this.m_isFinished = true;
      KiAppWaypointPlanSuccess planSuccess = KiAppSegmentPlanCommandEx.GetPlanSuccess(this.m_subtaskToPlan.KiSubTask);
      int o_firstIndex = 0;
      int o_secondIndex = 0;
      this.m_subtaskToPlan.WaypointIndexes(ref o_firstIndex, ref o_secondIndex);
      this.m_subtaskToPlan.Task.Waypoint(o_secondIndex).WaypointPlanSuccess = (CApAPPWaypointPlanSuccess) planSuccess;
    }
    return flag;
  }

  private void EndPlanning(bool i_success)
  {
    this.m_isStarted = false;
    this.m_isFinished = true;
    this.m_wasPlanningSuccessful = i_success;
    KiAppSegmentPlanCommandEx.EndPlanning(this.m_subtaskToPlan.KiSubTask, i_success);
  }

  private void SkipPlanning()
  {
    this.m_isStarted = false;
    this.m_isFinished = true;
    this.m_wasPlanningSuccessful = true;
  }

  private void ContinuePlanning()
  {
    bool flag = false;
    bool i_success = KiAppSegmentPlanCommandEx.ContinuePlanning(this.m_subtaskToPlan.KiSubTask, ref flag);
    if (!flag || !i_success)
    {
      this.EndPlanning(i_success);
    }
    else
    {
      if (!this.isTimeoutReached())
        return;
      this.m_wasPlanningTimeOut = true;
      this.EndPlanning(false);
    }
  }

  private bool isTimeoutReached()
  {
    bool flag = false;
    if (this.m_pathPlanningParams.TimeOutIsActivated && (double) this.m_elapsedTimerForTimeOut.ElapsedMilliseconds > this.m_pathPlanningParams.TimeOut * 1000.0)
      flag = true;
    return flag;
  }
}
